﻿using System;
using System.Collections.Generic;
using System.IO;
using Terraria.DataStructures;
using Terraria.ModLoader.IO;

namespace Terraria.ModLoader
{
	// Token: 0x020001F6 RID: 502
	public abstract class ModTileEntity : TileEntity
	{
		// Token: 0x1700019E RID: 414
		// (get) Token: 0x060015CD RID: 5581 RVA: 0x00010A32 File Offset: 0x0000EC32
		// (set) Token: 0x060015CE RID: 5582 RVA: 0x00010A3A File Offset: 0x0000EC3A
		public Mod mod { get; internal set; }

		// Token: 0x1700019F RID: 415
		// (get) Token: 0x060015CF RID: 5583 RVA: 0x00010A43 File Offset: 0x0000EC43
		// (set) Token: 0x060015D0 RID: 5584 RVA: 0x00010A4B File Offset: 0x0000EC4B
		public string Name { get; internal set; }

		// Token: 0x170001A0 RID: 416
		// (get) Token: 0x060015D1 RID: 5585 RVA: 0x00010A54 File Offset: 0x0000EC54
		// (set) Token: 0x060015D2 RID: 5586 RVA: 0x00010A5C File Offset: 0x0000EC5C
		public int Type { get; internal set; }

		// Token: 0x060015D3 RID: 5587 RVA: 0x0041459C File Offset: 0x0041279C
		internal static int ReserveTileEntityID()
		{
			if (ModNet.AllowVanillaClients)
			{
				throw new Exception("Adding tile entities breaks vanilla client compatiblity");
			}
			int num = ModTileEntity.nextTileEntity;
			ModTileEntity.nextTileEntity++;
			if (num > 255)
			{
				throw new Exception("Too many tile entities have been added");
			}
			return num;
		}

		// Token: 0x060015D4 RID: 5588 RVA: 0x00010A65 File Offset: 0x0000EC65
		public static ModTileEntity GetTileEntity(int type)
		{
			if (type < 3 || type >= ModTileEntity.nextTileEntity)
			{
				return null;
			}
			return ModTileEntity.tileEntities[type - 3];
		}

		// Token: 0x060015D5 RID: 5589 RVA: 0x00010A82 File Offset: 0x0000EC82
		internal static void Unload()
		{
			ModTileEntity.nextTileEntity = 3;
			ModTileEntity.tileEntities.Clear();
		}

		// Token: 0x060015D6 RID: 5590 RVA: 0x004145E4 File Offset: 0x004127E4
		public static int CountInWorld()
		{
			int num = 0;
			foreach (KeyValuePair<int, TileEntity> keyValuePair in TileEntity.ByID)
			{
				if (keyValuePair.Value.type >= 3)
				{
					num++;
				}
			}
			return num;
		}

		// Token: 0x060015D7 RID: 5591 RVA: 0x00010A94 File Offset: 0x0000EC94
		public static void Initialize()
		{
			TileEntity._UpdateStart += ModTileEntity.UpdateStartInternal;
			TileEntity._UpdateEnd += ModTileEntity.UpdateEndInternal;
			TileEntity._NetPlaceEntity += ModTileEntity.NetPlaceEntity;
		}

		// Token: 0x060015D8 RID: 5592 RVA: 0x00414648 File Offset: 0x00412848
		private static void UpdateStartInternal()
		{
			foreach (ModTileEntity modTileEntity in ModTileEntity.tileEntities)
			{
				modTileEntity.PreGlobalUpdate();
			}
		}

		// Token: 0x060015D9 RID: 5593 RVA: 0x0041469C File Offset: 0x0041289C
		private static void UpdateEndInternal()
		{
			foreach (ModTileEntity modTileEntity in ModTileEntity.tileEntities)
			{
				modTileEntity.PostGlobalUpdate();
			}
		}

		// Token: 0x060015DA RID: 5594 RVA: 0x004146F0 File Offset: 0x004128F0
		public static void NetPlaceEntity(int i, int j, int type)
		{
			ModTileEntity tileEntity = ModTileEntity.GetTileEntity(type);
			if (tileEntity == null)
			{
				return;
			}
			if (!tileEntity.ValidTile(i, j))
			{
				return;
			}
			int num = tileEntity.Place(i, j);
			ModTileEntity modTileEntity = (ModTileEntity)TileEntity.ByID[num];
			modTileEntity.OnNetPlace();
			NetMessage.SendData(86, -1, -1, null, num, (float)i, (float)j, 0f, 0, 0, 0);
		}

		// Token: 0x060015DB RID: 5595 RVA: 0x0041474C File Offset: 0x0041294C
		public static ModTileEntity ConstructFromType(int type)
		{
			ModTileEntity tileEntity = ModTileEntity.GetTileEntity(type);
			if (tileEntity == null)
			{
				return null;
			}
			return ModTileEntity.ConstructFromBase(tileEntity);
		}

		// Token: 0x060015DC RID: 5596 RVA: 0x0041476C File Offset: 0x0041296C
		public static ModTileEntity ConstructFromBase(ModTileEntity tileEntity)
		{
			ModTileEntity modTileEntity = (ModTileEntity)Activator.CreateInstance(tileEntity.GetType());
			modTileEntity.mod = tileEntity.mod;
			modTileEntity.Name = tileEntity.Name;
			modTileEntity.Type = tileEntity.Type;
			return modTileEntity;
		}

		// Token: 0x060015DD RID: 5597 RVA: 0x004147B0 File Offset: 0x004129B0
		public int Place(int i, int j)
		{
			ModTileEntity modTileEntity = ModTileEntity.ConstructFromBase(this);
			modTileEntity.Position = new Point16(i, j);
			modTileEntity.ID = TileEntity.AssignNewID();
			modTileEntity.type = (byte)this.Type;
			TileEntity.ByID[modTileEntity.ID] = modTileEntity;
			TileEntity.ByPosition[modTileEntity.Position] = modTileEntity;
			return modTileEntity.ID;
		}

		// Token: 0x060015DE RID: 5598 RVA: 0x00414814 File Offset: 0x00412A14
		public void Kill(int i, int j)
		{
			Point16 key = new Point16(i, j);
			if (TileEntity.ByPosition.ContainsKey(key))
			{
				TileEntity tileEntity = TileEntity.ByPosition[key];
				if ((int)tileEntity.type == this.Type)
				{
					((ModTileEntity)tileEntity).OnKill();
					TileEntity.ByID.Remove(tileEntity.ID);
					TileEntity.ByPosition.Remove(key);
				}
			}
		}

		// Token: 0x060015DF RID: 5599 RVA: 0x0041487C File Offset: 0x00412A7C
		public int Find(int i, int j)
		{
			Point16 key = new Point16(i, j);
			if (TileEntity.ByPosition.ContainsKey(key))
			{
				TileEntity tileEntity = TileEntity.ByPosition[key];
				if ((int)tileEntity.type == this.Type)
				{
					return tileEntity.ID;
				}
			}
			return -1;
		}

		// Token: 0x060015E0 RID: 5600 RVA: 0x00010AC9 File Offset: 0x0000ECC9
		public sealed override void WriteExtraData(BinaryWriter writer, bool networkSend)
		{
			this.NetSend(writer, networkSend);
		}

		// Token: 0x060015E1 RID: 5601 RVA: 0x00010AD3 File Offset: 0x0000ECD3
		public sealed override void ReadExtraData(BinaryReader reader, bool networkSend)
		{
			this.NetReceive(reader, networkSend);
		}

		// Token: 0x060015E2 RID: 5602 RVA: 0x00010ADD File Offset: 0x0000ECDD
		public virtual bool Autoload(ref string name)
		{
			return this.mod.Properties.Autoload;
		}

		// Token: 0x060015E3 RID: 5603 RVA: 0x0000D858 File Offset: 0x0000BA58
		public virtual TagCompound Save()
		{
			return null;
		}

		// Token: 0x060015E4 RID: 5604 RVA: 0x00006B58 File Offset: 0x00004D58
		public virtual void Load(TagCompound tag)
		{
		}

		// Token: 0x060015E5 RID: 5605 RVA: 0x00006B58 File Offset: 0x00004D58
		public virtual void NetSend(BinaryWriter writer, bool lightSend)
		{
		}

		// Token: 0x060015E6 RID: 5606 RVA: 0x00006B58 File Offset: 0x00004D58
		public virtual void NetReceive(BinaryReader reader, bool lightReceive)
		{
		}

		// Token: 0x060015E7 RID: 5607
		public abstract bool ValidTile(int i, int j);

		// Token: 0x060015E8 RID: 5608 RVA: 0x0000EAB6 File Offset: 0x0000CCB6
		public virtual int Hook_AfterPlacement(int i, int j, int type, int style, int direction)
		{
			return -1;
		}

		// Token: 0x060015E9 RID: 5609 RVA: 0x00006B58 File Offset: 0x00004D58
		public virtual void OnNetPlace()
		{
		}

		// Token: 0x060015EA RID: 5610 RVA: 0x00006B58 File Offset: 0x00004D58
		public virtual void PreGlobalUpdate()
		{
		}

		// Token: 0x060015EB RID: 5611 RVA: 0x00006B58 File Offset: 0x00004D58
		public virtual void PostGlobalUpdate()
		{
		}

		// Token: 0x060015EC RID: 5612 RVA: 0x00006B58 File Offset: 0x00004D58
		public virtual void OnKill()
		{
		}

		// Token: 0x04001518 RID: 5400
		public const int numVanilla = 3;

		// Token: 0x04001519 RID: 5401
		private static int nextTileEntity = 3;

		// Token: 0x0400151A RID: 5402
		internal static readonly List<ModTileEntity> tileEntities = new List<ModTileEntity>();
	}
}
